/*
 * Copyright (c) 2009, Hamish Morgan. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the University of Sussex nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * LocustsAdmin.java
 *
 * Created on 31-Aug-2009, 14:29:30
 */
package locusts.server.admin;

import java.awt.BorderLayout;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableModel;
import locusts.Main;
import locusts.client.Client;
import locusts.client.ClientConfig;
import locusts.common.Constants;
import locusts.common.entities.Entity;
import locusts.common.entities.EntityList;
import locusts.common.entities.EntityType;
import locusts.server.Game;
import locusts.server.Server;
import locusts.server.ServerNetHandler;
import org.apache.mina.common.IoSession;
import org.apache.mina.management.StatCollector;

/**
 * I Swing GUI frame than allows a game to be administered by a super user as
 * well as played.
 *
 * @author Hamish Morgan
 */
public class LocustsAdmin extends javax.swing.JFrame {

    private Server server;
    private Game game;
    private int port;

    /** Creates new form LocustsAdmin
     * @param game
     * @param port
     * @param server
     */
    public LocustsAdmin(Server server) {
        this.server = server;
        this.game = server.getGame();
        this.port = server.getNetHandler().getAddress().getPort();

        initComponents();

        JComboBox entTypeCB = new JComboBox(new EntityTypeComboBoxModel(game.
                getEntityTypes()));
        entitiesTable.setDefaultEditor(EntityType.class,
                new DefaultCellEditor(entTypeCB));
        entitiesTable.getSelectionModel().addListSelectionListener(
                new ListSelectionListener() {

                    {
                        updateButtons();
                    }

                    public void valueChanged(ListSelectionEvent e) {
                        updateButtons();
                    }

                    private void updateButtons() {
                        final int n = entitiesTable.getSelectedRowCount();
                        entityDelteButton.setEnabled(n > 0);
                        entityEditButton.setEnabled(n == 1);
                    }
                });

        JComboBox farmCB = new JComboBox(new EntityComboBoxModel(
                game.getEntities(),
                game.getEntityTypes().getName(Constants.FARM)));
        playersTable.setDefaultEditor(Entity.class, new DefaultCellEditor(
                farmCB));


        gameTab.setLayout(new BorderLayout());
        ClientConfig config = new ClientConfig();
        config.setRemotePort(port);
        config.setRemoteHost(Main.DEFAULT_HOST);
        config.setTouchEnabled(false);
        Client client = new Client(config);
        client.getPanel().getOvRenderer().setDrawClientViews(
                true);
        gameTab.add(client.getPanel(), BorderLayout.CENTER);
        new Timer().schedule(new TimerTask() {

            @Override
            public void run() {
                initData();
            }
        }, 0, 1000);

    }

    private void initData() {
        final ServerNetHandler nh = server.getNetHandler();

        final InetSocketAddress ad = nh.getAddress();
        ipAddressLabel.setText(ad.getAddress().toString());
        portLabel.setText("" + ad.getPort());


        long totalBytesWritten = 0;
        long totalBytesRead = 0;
        long totalMsgsWritten = 0;
        long totalMsgsRead = 0;
        final Set<SocketAddress> msa = nh.getAcceptor().
                getManagedServiceAddresses();
        for (SocketAddress a : msa) {
            Set<IoSession> ms = nh.getAcceptor().getManagedSessions(a);
            for (IoSession s : ms) {
                totalBytesRead += s.getReadBytes();
                totalMsgsRead += s.getReadMessages();
                totalBytesWritten += s.getWrittenBytes();
                totalMsgsWritten += s.getWrittenMessages();
            }
        }
        totalBytesReadLabel.setText("" + totalBytesRead);
        totalBytesWrittenLabel.setText("" + totalBytesWritten);
        totalMsgsReadLabel.setText("" + totalMsgsRead);
        totalMsgsWrittenLabel.setText("" + totalMsgsWritten);

        final StatCollector sc = nh.getStats();
        bytesReadThroughput.setText("" + sc.getBytesReadThroughput());
        bytesWrittenThroughput.setText("" + sc.getBytesWrittenThroughput());
        msgsReadThroughput.setText("" + sc.getMsgReadThroughput());
        msgsWrittenThroughput.setText("" + sc.getMsgWrittenThroughput());
        sessionCountLabel.setText("" + sc.getSessionCount());
        totalSessionsLabel.setText("" + sc.getTotalProcessedSessions());
        isRunningLabel.setText(sc.isRunning() ? "Running" : "Not Running");

        numEntitiesLabel.setText("" + game.getEntities().size());
        numPlayersLabel.setText("" + game.getPlayers().size());
        frameRateLabel.setText("" + game.getFrameCounter().getFps() +
                " (Limitted at " + Game.MAX_FPS + " FPS)");
    }

    @Override
    public void repaint() {
        super.repaint();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        adminTabbedPane = new javax.swing.JTabbedPane();
        statusTab = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        ipAddressLabel = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        portLabel = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        bytesReadThroughput = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        bytesWrittenThroughput = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        msgsWrittenThroughput = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        msgsReadThroughput = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        sessionCountLabel = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        totalSessionsLabel = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        isRunningLabel = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        totalBytesReadLabel = new javax.swing.JLabel();
        jLabel14 = new javax.swing.JLabel();
        totalBytesWrittenLabel = new javax.swing.JLabel();
        jLabel15 = new javax.swing.JLabel();
        totalMsgsReadLabel = new javax.swing.JLabel();
        jLabel16 = new javax.swing.JLabel();
        totalMsgsWrittenLabel = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jLabel19 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();
        numPlayersLabel = new javax.swing.JLabel();
        numEntitiesLabel = new javax.swing.JLabel();
        jLabel21 = new javax.swing.JLabel();
        frameRateLabel = new javax.swing.JLabel();
        gameTab = new javax.swing.JPanel();
        entitiesTab = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        entitiesTable = new javax.swing.JTable();
        jPanel3 = new javax.swing.JPanel();
        entityDelteButton = new javax.swing.JButton();
        entityEditButton = new javax.swing.JButton();
        entityAddButton = new javax.swing.JButton();
        typeDataTab = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        playersTab = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        playersTable = new javax.swing.JTable();
        clientsTab = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        jTable3 = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        adminTabbedPane.setOpaque(true);

        statusTab.setOpaque(false);

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Networking"));
        jPanel4.setFocusable(false);
        jPanel4.setOpaque(false);

        jLabel1.setText("Address: ");

        ipAddressLabel.setText("ip_address");

        jLabel2.setText(":");

        portLabel.setText("port");

        jLabel4.setText("Bytes Throughput:");

        bytesReadThroughput.setText("1234");

        jLabel6.setText("read");

        bytesWrittenThroughput.setText("1234");

        jLabel8.setText("written.");

        jLabel5.setText("Msgs Throughput:");

        jLabel9.setText("written.");

        msgsWrittenThroughput.setText("1234");

        jLabel7.setText("read");

        msgsReadThroughput.setText("1234");

        jLabel10.setText("Num Sessions:");

        sessionCountLabel.setText("session_count");

        jLabel12.setText("Total Sessions:");

        totalSessionsLabel.setText("total_sessions");

        jLabel13.setText("Is Running:");

        isRunningLabel.setText("is_running");

        jLabel3.setText("Total Bytes:");

        jLabel11.setText("Total Msgs:");

        totalBytesReadLabel.setText("1234");

        jLabel14.setText("read");

        totalBytesWrittenLabel.setText("1234");

        jLabel15.setText("written.");

        totalMsgsReadLabel.setText("1234");

        jLabel16.setText("read");

        totalMsgsWrittenLabel.setText("1234");

        jLabel17.setText("written.");

        org.jdesktop.layout.GroupLayout jPanel4Layout = new org.jdesktop.layout.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jPanel4Layout.createSequentialGroup()
                        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jLabel5)
                            .add(jLabel10)
                            .add(jLabel12)
                            .add(jLabel13)
                            .add(jLabel3)
                            .add(jLabel11))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jPanel4Layout.createSequentialGroup()
                                .add(totalBytesReadLabel)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel14)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(totalBytesWrittenLabel)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel15))
                            .add(isRunningLabel)
                            .add(totalSessionsLabel)
                            .add(sessionCountLabel)
                            .add(jPanel4Layout.createSequentialGroup()
                                .add(msgsReadThroughput)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel7)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(msgsWrittenThroughput)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel9))
                            .add(jPanel4Layout.createSequentialGroup()
                                .add(totalMsgsReadLabel)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel16)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(totalMsgsWrittenLabel)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel17))))
                    .add(jPanel4Layout.createSequentialGroup()
                        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jLabel4)
                            .add(jLabel1))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jPanel4Layout.createSequentialGroup()
                                .add(ipAddressLabel)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel2)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(portLabel))
                            .add(jPanel4Layout.createSequentialGroup()
                                .add(bytesReadThroughput)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel6)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(bytesWrittenThroughput)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jLabel8)))))
                .addContainerGap(210, Short.MAX_VALUE))
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel1)
                    .add(ipAddressLabel)
                    .add(jLabel2)
                    .add(portLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel4)
                    .add(bytesReadThroughput)
                    .add(jLabel6)
                    .add(bytesWrittenThroughput)
                    .add(jLabel8))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel5)
                    .add(msgsReadThroughput)
                    .add(jLabel7)
                    .add(msgsWrittenThroughput)
                    .add(jLabel9))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel10)
                    .add(sessionCountLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel12)
                    .add(totalSessionsLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel13)
                    .add(isRunningLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel3)
                    .add(totalBytesReadLabel)
                    .add(jLabel14)
                    .add(totalBytesWrittenLabel)
                    .add(jLabel15))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel11)
                    .add(totalMsgsReadLabel)
                    .add(jLabel16)
                    .add(totalMsgsWrittenLabel)
                    .add(jLabel17))
                .addContainerGap(26, Short.MAX_VALUE))
        );

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Game"));
        jPanel1.setFocusable(false);
        jPanel1.setOpaque(false);

        jLabel19.setText("Players:");

        jLabel20.setText("Entities:");

        numPlayersLabel.setText("jLabel21");

        numEntitiesLabel.setText("jLabel21");

        jLabel21.setText("Frame Rate:");

        frameRateLabel.setText("jLabel21");

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jLabel19)
                    .add(jLabel20)
                    .add(jLabel21))
                .add(49, 49, 49)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(frameRateLabel)
                    .add(numEntitiesLabel)
                    .add(numPlayersLabel))
                .addContainerGap(321, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel19)
                    .add(numPlayersLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel20)
                    .add(numEntitiesLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel21)
                    .add(frameRateLabel))
                .addContainerGap(41, Short.MAX_VALUE))
        );

        org.jdesktop.layout.GroupLayout statusTabLayout = new org.jdesktop.layout.GroupLayout(statusTab);
        statusTab.setLayout(statusTabLayout);
        statusTabLayout.setHorizontalGroup(
            statusTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, statusTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(statusTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        statusTabLayout.setVerticalGroup(
            statusTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(statusTabLayout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(18, 18, 18)
                .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        adminTabbedPane.addTab("Status", statusTab);

        org.jdesktop.layout.GroupLayout gameTabLayout = new org.jdesktop.layout.GroupLayout(gameTab);
        gameTab.setLayout(gameTabLayout);
        gameTabLayout.setHorizontalGroup(
            gameTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 568, Short.MAX_VALUE)
        );
        gameTabLayout.setVerticalGroup(
            gameTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 469, Short.MAX_VALUE)
        );

        adminTabbedPane.addTab("Game", gameTab);

        entitiesTab.setLayout(new java.awt.BorderLayout());

        entitiesTable.setModel(new EntitiesTableModel(game));
        jScrollPane1.setViewportView(entitiesTable);

        entitiesTab.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        entityDelteButton.setText("Delete");
        entityDelteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                entityDelteButtonActionPerformed(evt);
            }
        });
        jPanel3.add(entityDelteButton);

        entityEditButton.setText("Edit");
        entityEditButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                entityEditButtonActionPerformed(evt);
            }
        });
        jPanel3.add(entityEditButton);

        entityAddButton.setText("Add");
        entityAddButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                entityAddButtonActionPerformed(evt);
            }
        });
        jPanel3.add(entityAddButton);

        entitiesTab.add(jPanel3, java.awt.BorderLayout.PAGE_END);

        adminTabbedPane.addTab("Entities", entitiesTab);

        typeDataTab.setLayout(new java.awt.BorderLayout());

        jTable1.setModel(new TypeDataTableModel(game));
        jScrollPane2.setViewportView(jTable1);

        typeDataTab.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        adminTabbedPane.addTab("Type Data", typeDataTab);

        playersTab.setLayout(new java.awt.BorderLayout());

        playersTable.setModel(new PlayersTableModel(game));
        jScrollPane3.setViewportView(playersTable);

        playersTab.add(jScrollPane3, java.awt.BorderLayout.CENTER);

        adminTabbedPane.addTab("Players", playersTab);

        clientsTab.setLayout(new java.awt.BorderLayout());

        jTable3.setModel(new ClientsTableModel(server));
        jScrollPane4.setViewportView(jTable3);

        clientsTab.add(jScrollPane4, java.awt.BorderLayout.CENTER);

        adminTabbedPane.addTab("Clients", clientsTab);

        getContentPane().add(adminTabbedPane, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void entityAddButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_entityAddButtonActionPerformed
        // TODO add your handling code here:
        new AddEntityDialog(game, this, true).setVisible(true);
}//GEN-LAST:event_entityAddButtonActionPerformed

    private void entityEditButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_entityEditButtonActionPerformed
        // TODO add your handling code here:
        int row = entitiesTable.getSelectedRow();
        if (row == -1)
            return;
        int col = getIdCol();
        if (col == -1)
            return;
        TableModel model = entitiesTable.getModel();
        Entity e = game.getEntities().getById((Integer) (model.getValueAt(row,
                col)));
        new EditEntityFrame(game, e).setVisible(rootPaneCheckingEnabled);
}//GEN-LAST:event_entityEditButtonActionPerformed

    private void entityDelteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_entityDelteButtonActionPerformed
        // TODO add your handling code here:
        int rows[] = entitiesTable.getSelectedRows();
        if (rows.length == 0)
            return;
        EntityList ents = game.getEntities();
        Entity[] remove = new Entity[rows.length];

        TableModel model = entitiesTable.getModel();
        int col = getIdCol();

        for (int i = 0; i < rows.length; i++) {
            remove[i] = ents.getById(
                    (Integer) (model.getValueAt(rows[i], col)));
            //ents.get(i);
        }
        for (int i = 0; i < rows.length; i++) {
            game.removeEntity(remove[i]);
        }
}//GEN-LAST:event_entityDelteButtonActionPerformed

    private int getIdCol() {
        TableModel model = entitiesTable.getModel();
        int col = -1;
        for (int i = 0; i < model.getColumnCount(); i++) {
            if (model.getColumnName(i).equals("Id")) {
                col = i;
                break;
            }
        }
        return col;
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTabbedPane adminTabbedPane;
    private javax.swing.JLabel bytesReadThroughput;
    private javax.swing.JLabel bytesWrittenThroughput;
    private javax.swing.JPanel clientsTab;
    private javax.swing.JPanel entitiesTab;
    private javax.swing.JTable entitiesTable;
    private javax.swing.JButton entityAddButton;
    private javax.swing.JButton entityDelteButton;
    private javax.swing.JButton entityEditButton;
    private javax.swing.JLabel frameRateLabel;
    private javax.swing.JPanel gameTab;
    private javax.swing.JLabel ipAddressLabel;
    private javax.swing.JLabel isRunningLabel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel21;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JTable jTable1;
    private javax.swing.JTable jTable3;
    private javax.swing.JLabel msgsReadThroughput;
    private javax.swing.JLabel msgsWrittenThroughput;
    private javax.swing.JLabel numEntitiesLabel;
    private javax.swing.JLabel numPlayersLabel;
    private javax.swing.JPanel playersTab;
    private javax.swing.JTable playersTable;
    private javax.swing.JLabel portLabel;
    private javax.swing.JLabel sessionCountLabel;
    private javax.swing.JPanel statusTab;
    private javax.swing.JLabel totalBytesReadLabel;
    private javax.swing.JLabel totalBytesWrittenLabel;
    private javax.swing.JLabel totalMsgsReadLabel;
    private javax.swing.JLabel totalMsgsWrittenLabel;
    private javax.swing.JLabel totalSessionsLabel;
    private javax.swing.JPanel typeDataTab;
    // End of variables declaration//GEN-END:variables
}
